//
//  PageViewController.swift
//  
//
//  Created by 孙长坦 on 2022/6/16.
//

import Foundation
import UIKit
import Logging
import RxSwift
import LibUI
import LibService


open class PageViewController: BaseViewController, PageControllerProtocol {
    var logger = Logger(label: "LibModuleManager.PageViewController")
    
    private let disposeBag: DisposeBag = DisposeBag()
    
    public override var preferredStatusBarStyle: UIStatusBarStyle {
        return page.config.statusBarType.value.statusBarStyle
    }
    
    public unowned var page: PageProtocol
    
    public lazy var navigationBar: NavigationBar = {
        let navigationBar = NavigationBar()
        
        navigationBar.onBackButtonTap = {
            _ = ServiceManager.shared.routerService?.pop(animated: true)
        }
        
        view.addSubview(navigationBar)
        
        return navigationBar
    }()
    
    public var contentView: UIView? {
        didSet {
            oldValue?.removeFromSuperview()
            
            guard let contentView = contentView, isViewLoaded else {
                return
            }
            view.addSubview(contentView)
        }
    }
    
    public init(page: PageProtocol) {
        self.page = page
        super.init(nibName: nil, bundle: nil)
    }
    
    required public init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        page.module.removePage(type: page.type, id: page.id)
    }
    
    open override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .white
        
        if let contentView = contentView {
            view.addSubview(contentView)
        }
        
        page.config.navigationBarStyle
            .subscribe(onNext: { [weak self] _ in
                self?.initNavigationBar()
            })
            .disposed(by: disposeBag)
        
        page.config.rightMenus
            .subscribe(onNext: { [weak self] rightMenus in
                self?.navigationBar.rightMenus = rightMenus
            })
            .disposed(by: disposeBag)
        
        page.config.statusBarType
            .subscribe { [weak self] statusBarType in
                self?.setNeedsStatusBarAppearanceUpdate()
            }
            .disposed(by: disposeBag)
        
        initConstraints()
        
        navigationBar.onMenuTap = { [weak self] menuData in
            guard let menuData = menuData else {
                return
            }
            
            self?.onMenuTap(menuData: menuData)
        }
    }
    
    open override func willMove(toParent parent: UIViewController?) {
        super.willMove(toParent: parent)
    }
    
    open override func didMove(toParent parent: UIViewController?) {
        super.didMove(toParent: parent)
        
        if parent == nil {
            page.completion?(.success, page.completionParam)
        }
    }
    
    open override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
        super.dismiss(animated: flag, completion: completion)
        
        page.completion?(.success, page.completionParam)
    }
    
    open override func updateViewConstraints() {
        super.updateViewConstraints()
        
        initConstraints()
    }
    
    open override func viewSafeAreaInsetsDidChange() {
        super.viewSafeAreaInsetsDidChange()
        
        view.setNeedsUpdateConstraints()
    }
    
    func initConstraints() {
        let navigationBarType = page.config.navigationBarStyle.value.type
        
        if navigationBarType != .hide {
            view.bringSubviewToFront(navigationBar)
            
            navigationBar.snp.remakeConstraints { make in
                make.top.left.right.equalToSuperview()
                make.height.equalTo(view.safeAreaInsets.top + NavigationBar.height)
            }
        }
        
        contentView?.snp.remakeConstraints { make in
            if navigationBarType == .opaque {
                make.top.equalTo(navigationBar.snp.bottom)
            } else {
                navigationBar.backgroundColor = .clear
                make.top.equalToSuperview()
            }
            make.left.right.bottom.equalToSuperview()
        }
    }
    
    func initNavigationBar() {
        guard page.config.navigationBarStyle.value.type != .hide else {
            navigationBar.isHidden = true
            view.setNeedsUpdateConstraints()
            return
        }
        
        navigationBar.isHidden = false
        
        navigationBar.set(title: page.config.title, subTitle: page.config.subTitle)
        navigationBar.titleAlignment = page.config.titleAlignment.textAlignment
        navigationBar.rightMenus = page.config.rightMenus.value
        
        if let backgroundColor = page.config.navigationBarStyle.value.backgroundColor {
            navigationBar.backgroundColor = backgroundColor
        }
        
        if let tintColor = page.config.navigationBarStyle.value.tintColor {
            navigationBar.tintColor = tintColor
        }
        
        page.config.titleObservable
            .subscribe(onNext: {[weak self] (title, subTitle) in
                self?.navigationBar.set(title: title, subTitle: subTitle)
            })
            .disposed(by: disposeBag)
        
        view.setNeedsUpdateConstraints()
    }
    
    func onMenuTap(menuData: MenuData) {
        if let url = menuData.url {
            ServiceManager.shared
                .routerService?.open(url: url, params: nil, completion: nil)
        } else if let webView = menuData.webView, let onTap = menuData.onTap {
            webView.evaluateJavaScript(onTap) {[weak self] value, error in
                self?.logger.info("\(value ?? "No return value"), \(error?.localizedDescription ?? "Error nil")")
            }
        }
    }
}
